#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <math.h>

#define WRITE_BUFF_SIZE (1024 * 4)
#define PI 3.14159265358979323846

/// 正弦波 CSV 生成

void write_csv(char *FileName, uint8_t *data, uint32_t len)
{
	FILE *fp = NULL;

	fp = fopen(FileName, "aw");
	if (fp == NULL)
	{
		printf("Error opening file!\n");
		return;
	}

	fwrite(data, 1, len, fp);

	fclose(fp);
}

/// @brief 清空文件内容
/// @param filename
void Clear_Csv_File(const char *filename)
{
	if (filename == NULL)
	{
		printf("Filename is NULL\n");
		return;
	}

	// 打开文件
	FILE *file = fopen(filename, "w");
	if (file == NULL)
	{
		printf("Failed to open file: %s\n", filename);
		return;
	}

	// 清空文件内容
	if (fprintf(file, "") < 0)
	{
		printf("Failed to clear file: %s\n", filename);
	}

	// 关闭文件夹
	fclose(file);
}

/// @brief 输出命令行参数
/// @param argc
/// @param argv
void Param_Output(int argc, char *argv[])
{
	for (int i = 0; i < argc; i++)
	{
		printf("argv[%d] = %s\n", i, argv[i]);
	}
}

/// @brief 生成二值化数据，并写入CSV文件
/// @param Count
/// @param Range
/// @param Period
void Gen_BinaryWave(char *fileName, uint32_t Count, uint32_t Range, uint32_t Period)
{

	uint8_t *WriteBuf = NULL,
			LineBuf[128] = {0};

	uint32_t LineIndex = 0,
			 BuffLen = 0;

	// 缓冲区
	WriteBuf = (uint8_t *)malloc(WRITE_BUFF_SIZE);
	if (WriteBuf == NULL)
	{
		printf("Error allocating memory!\n");
		return;
	}
	memset(WriteBuf, 0, WRITE_BUFF_SIZE);

	// 写入标题行
	sprintf(LineBuf, "Index,Value\n,,,Count,%d,Range,%d,Period,%d", Count, Range, Period);
	BuffLen += strlen((char *)LineBuf);
	sprintf(WriteBuf, "%s", LineBuf);

	// 生成随机数并写入文件
	for (uint32_t i = 0; i < Count; i++)
	{
		for (float j = 0; j < Period; j++)
		{
			memset(LineBuf, 0, sizeof(LineBuf));

			double value = 0;
			if (i == 0)
			{
				value = 0;
			}
			else
			{
				if (i % 2 == 1)
				{
					value -= Range;
				}
				else
				{
					value = Range;
				}
			}

			sprintf(LineBuf, "\n%d,%f", LineIndex, value);

			// 写入缓存区
			sprintf(WriteBuf + BuffLen, "%s", LineBuf);
			BuffLen += strlen((char *)LineBuf);

			// 将结果写入文件
			if (BuffLen >= WRITE_BUFF_SIZE - 64)
			{
				write_csv(fileName, WriteBuf, BuffLen);
				memset(WriteBuf, 0, WRITE_BUFF_SIZE);
				BuffLen = 0;
			}

			LineIndex++;
		}
	}

	if (BuffLen > 0)
	{
		write_csv(fileName, WriteBuf, BuffLen);
	}

	// 释放内存
	if (WriteBuf != NULL)
	{
		free(WriteBuf);
		WriteBuf = NULL;
	}
}

int main(int argc, char *argv[])
{
	uint8_t fileName[20] = {0};

	// 参数:  数量  范围  周期
	uint32_t Count = 0, Range = 0, Period = 0;

	//  参数输出
	Param_Output(argc, argv);

	// 帮助描述
	if (argc < 5)
	{
		printf("Usage: %s <filename> <count> <period> <range>\n", argv[0]);
		printf("Example: %s Binary 1000 1 10\n", argv[0]);
		return 1;
	}

	// 解析命令行参数
	sprintf(fileName, "%s.csv", argv[1]);
	Count = atoi(argv[2]);
	Range = atoi(argv[3]);
	Period = atoi(argv[4]);

	// 清空文件内容
	Clear_Csv_File(fileName);

	// 生成二值化数据并写入CSV文件
	Gen_BinaryWave(fileName, Count, Range, Period);

	printf("Data Written to %s\n", fileName);
	return 0;
}